package com.plian.system.controller.im;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.plian.Tools.Func;
import com.plian.Tools.StringPool;
import com.plian.Tools.StringUtil;
import com.plian.Tools.base.BaseController;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.annotation.LogOperation;
import com.plian.system.common.status.CustomCode;
import com.plian.system.config.Resubmit;
import com.plian.system.dto.im.BaseInvestmentExecutionDTO;
import com.plian.system.dto.im.BaseInvestmentExecutionNewDTO;
import com.plian.system.dto.im.MainProjectSituationDTO;
import com.plian.system.entity.im.BaseInvestmentExecutionNew;
import com.plian.system.entity.im.ProjectInfo;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.R;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.search.TokenSearch;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.service.im.IBaseInvestmentExecutionNewService;
import com.plian.system.service.im.IEffectiveInvestmentService;
import com.plian.system.service.im.IMainProjectSituationService;
import com.plian.system.service.im.IProjectInfoService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.vo.im.BaseInvestmentExecutionNewVO;
import com.plian.system.vo.im.EffectiveInvestmentVO;
import com.plian.system.vo.im.ExecutionProjectSituationVO;
import com.plian.system.vo.im.InvestmentMonthSummaryVO;
import com.plian.system.vo.report.ChartsVO;
import com.plian.system.vo.report.ReportReturnVO;
import com.plian.system.wrapper.im.BaseInvestmentExecutionNewWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 控制器
 *
 * @author
 * @since 2019-09-27
 */
@RestController
@AllArgsConstructor
@RequestMapping("api/baseinvestmentexecutionNew")
@Api(value = "项目投资计划执行（新需求）", tags = "项目投资计划执行接口")
public class BaseInvestmentExecutionNewController extends BaseController {

	private IBaseInvestmentExecutionNewService baseInvestmentExecutionService;

	private IMainProjectSituationService mainProjectSituationService;

	private IEffectiveInvestmentService effectiveInvestmentService;

	private FormWorkflowService formWorkflowService;

	private BaseInvestmentExecutionNewWrapper baseInvestmentExecutionWrapper;

	private IProjectInfoService projectInfoService;

	/**
	 * 详情
	 */
	@PostMapping("/detail")
	@ApiOperation(value = "详情")
	public R<BaseInvestmentExecutionNewVO> detail(@RequestBody BaseInvestmentExecutionNew baseInvestmentExecution) {
		BaseInvestmentExecutionNew detail = baseInvestmentExecutionService.getOne(Condition.getQueryWrapper(baseInvestmentExecution));
		BaseInvestmentExecutionNewVO baseInvestmentExecutionVO = baseInvestmentExecutionWrapper.entityToVO(detail);
		return baseInvestmentExecutionService.getDetailObj(baseInvestmentExecutionVO);
	}

	/**
	 * 分页
	 */
	@PostMapping("/list")
	@ApiOperation(value = "分页")
	public ListResult<BaseInvestmentExecutionNewVO> list(@RequestBody Query query) {
		List<SearchEntity> entityList = query.getSearch();
		if (query.getAscs()==null&&query.getDescs()==null){
			query.setDescs("filing_month");
		}
		QueryWrapper<BaseInvestmentExecutionNew> queryWrapper = SearchParamEntiy.getQueryWrapper(
				Condition.getQueryWrapper(new BaseInvestmentExecutionNew()), entityList
		);
		TokenSearch<BaseInvestmentExecutionNew> tokenSearch = new TokenSearch<>();
		tokenSearch.addTokenQuery(queryWrapper, query);

		IPage<BaseInvestmentExecutionNew> pages = baseInvestmentExecutionService.page(Condition.getPage(query), queryWrapper);
		List<BaseInvestmentExecutionNewVO> baseInvestmentExecutionVOS = baseInvestmentExecutionWrapper.entityToVO(pages.getRecords());
		List<Long> projectIds = baseInvestmentExecutionVOS.stream().map(BaseInvestmentExecutionNewVO::getImProjectId).collect(Collectors.toList());
		if(CollectionUtil.isNotEmpty(projectIds)){
			LambdaQueryWrapper<ProjectInfo> queryWrapper1 = new LambdaQueryWrapper<>();
			queryWrapper1.select(ProjectInfo::getProjectName);
			queryWrapper1.in(ProjectInfo::getId,projectIds);
			List<ProjectInfo> projectList = projectInfoService.list(queryWrapper1);
			Map<Long, String> collect = projectList.stream().collect(Collectors.toMap(ProjectInfo::getId, ProjectInfo::getProjectName,(a,b) -> b));
			baseInvestmentExecutionVOS.forEach(a -> a.setProjectName(collect.get(a.getImProjectId())));
		}
		ListResult<BaseInvestmentExecutionNewVO> listResult = new ListResult<>(CommonCode.SUCCESS);
		listResult.setList(baseInvestmentExecutionVOS);
		listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
		return listResult;

	}

	/**
	 * 新增或修改
	 */
	@PostMapping("/submit")
	@Resubmit(delaySeconds = 0)
	@LogOperation("项目投资计划执行-提交")
	@ApiOperation(value = "新增或修改")
	public R submit(@Valid @RequestBody BaseInvestmentExecutionNew baseInvestmentExecution) {
		String checkMessage = baseInvestmentExecutionService.checkMonth(baseInvestmentExecution);
		if (StringUtil.isNotBlank(checkMessage)){
			return new R(CustomCode.builder().message(checkMessage).code(1999).success(false).build());
		}

//		checkMessage = effectiveInvestmentService.check(baseInvestmentExecution.getEffectiveInvestment());
//		if (StringUtil.isNotBlank(checkMessage)){
//			return new R(CustomCode.builder().message(checkMessage).code(1999).success(false).build());
//		}

		boolean result = baseInvestmentExecutionService.submit(baseInvestmentExecution);
		HashMap<String, Object> processVariable = new HashMap<>();
		formWorkflowService.startProcessAndSimulate(String.valueOf(baseInvestmentExecution.getId()),baseInvestmentExecution.getFormType(),processVariable);

		return result ? new R(CommonCode.SUCCESS) : new R(CommonCode.FAIL);
	}

	/**
	 * 删除
	 */
	@PostMapping("/remove")
	@ApiOperation(value = "删除")
	@LogOperation("项目投资计划执行-删除")
	public R remove(@RequestBody PageData pd) {
		List<String> ids = (List<String>)pd.get("ids");
		return baseInvestmentExecutionService.deleteLogic(Func.toLongList(StringUtils.join(ids, StringPool.COMMA)))
				? new R(CommonCode.SUCCESS) : new R(CommonCode.FAIL);
	}

	/**
	 * 重点项目完成情况汇总(按项目类别分类）
	 */
	@PostMapping("/statisticsByNature")
	@ApiOperation(value = "重点项目完成情况汇总(按项目类别分类）")
	public R<ReportReturnVO> statisticsByNature(@Valid @RequestBody(required = false) MainProjectSituationDTO mainProjectSituationDTO) {
		ReportReturnVO reportReturnVO = mainProjectSituationService.statisticsByNature(mainProjectSituationDTO);
		R<ReportReturnVO> results = new R<>(CommonCode.SUCCESS);
		results.setPageData(reportReturnVO);
		return results;
	}

	/**
	 * 重点项目完成情况汇总(按企业分类）
	 */
	@PostMapping("/statisticsByUnit")
	@ApiOperation(value = "重点项目完成情况汇总(按企业分类）")
	public R<ReportReturnVO> statisticsByUnit(@Valid @RequestBody(required = false) MainProjectSituationDTO mainProjectSituationDTO) {
		ReportReturnVO reportReturnVO = mainProjectSituationService.statisticsByUnit(mainProjectSituationDTO);
		R<ReportReturnVO> results = new R<>(CommonCode.SUCCESS);
		results.setPageData(reportReturnVO);
		return results;
	}

	/**
	 * 市属国有企业有效投资月度汇总表
	 */
	@PostMapping("/summary")
	@ApiOperation(value = "市属国有企业有效投资月度汇总表")
	public ListResult<InvestmentMonthSummaryVO> summary(@Valid @RequestBody BaseInvestmentExecutionNewDTO baseInvestmentExecutionDTO) {
		BaseInvestmentExecutionDTO dto = new BaseInvestmentExecutionDTO();
		BeanUtils.copyProperties(baseInvestmentExecutionDTO,dto);
		List<InvestmentMonthSummaryVO> results = effectiveInvestmentService.summary(dto);
		ListResult<InvestmentMonthSummaryVO> listResult = new ListResult<>(CommonCode.SUCCESS);
		listResult.setList(results);
		return listResult;
	}

	/**
	 * 生成excel文件
	 * @param id
	 * @return
	 */
	@GetMapping("/export/{id}")
	@ApiOperation(value = "生成excel文件")
	public ObjResult export(@PathVariable Long id){
		PageData pd = new PageData();
		pd.put("key", baseInvestmentExecutionService.export(id));
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		objResult.setPageData(pd);
		return objResult;
	}

	/**
	 * 下载excel文件 并删除
	 * @param key
	 * @param response
	 * @param os
	 */
	@GetMapping("/download/{key}")
	@ApiOperation(value = "下载excel文件并删除")
	public void download(@PathVariable String key, HttpServletResponse response, OutputStream os){
		baseInvestmentExecutionService.download(key, response, os);
	}


	/**
	 * 获取上月填报数据
	 * @param baseInvestmentExecution
	 * @return
	 */
	@PostMapping("/last")
	@ApiOperation(value = "获取上月填报数据")
	public R last(@RequestBody BaseInvestmentExecutionNew baseInvestmentExecution) {
		return baseInvestmentExecutionService.getLastMonthObj(baseInvestmentExecution);
	}

	/**
	 * 重大项目考核明细表-统计用（   月度）
	 */
	@PostMapping("/summaryDetail")
	@ApiOperation(value = "重大项目考核明细表-统计用（月度）")
	public R<ReportReturnVO> summaryDetail(@Valid @RequestBody MainProjectSituationDTO mainProjectSituationDTO) {
		ReportReturnVO reportReturnVO = mainProjectSituationService.summaryDetail(mainProjectSituationDTO);
		R<ReportReturnVO> results = new R<>(CommonCode.SUCCESS);
		results.setPageData(reportReturnVO);
		return results;
	}

	/**
	 * 有效投资考核明细表-统计用（   月度）
	 */
	@PostMapping("/effectiveSummary")
	@ApiOperation(value = "有效投资考核明细表-统计用（月度）")
	public R<ReportReturnVO> effectiveSummary(@Valid @RequestBody BaseInvestmentExecutionNewDTO baseInvestmentExecutionDTO) {
		BaseInvestmentExecutionDTO dto = new BaseInvestmentExecutionDTO();
		BeanUtils.copyProperties(baseInvestmentExecutionDTO,dto);
		ReportReturnVO reportReturnVO = effectiveInvestmentService.effectiveSummary(dto);
		R<ReportReturnVO> results = new R<>(CommonCode.SUCCESS);
		results.setPageData(reportReturnVO);
		return results;
	}

	/**
	 * 年度项目投资计划完成率 柱状图
	 * @param baseInvestmentExecutionDTO
	 * @return
	 */
	@PostMapping("/statistics/completeProportion")
	@ApiOperation(value = "年度项目投资计划完成率-柱状图")
	public R<ChartsVO> statisticsCompanyProportion(@RequestBody BaseInvestmentExecutionNewDTO baseInvestmentExecutionDTO) {
		R<ChartsVO> result = new R<>(CommonCode.SUCCESS);
		result.setPageData(baseInvestmentExecutionService.statisticsCompanyProportion(baseInvestmentExecutionDTO));
		return result;
	}

	/**
	 * 企业完成投资情况
	 * @param baseInvestmentExecutionDTO
	 * @return
	 */
	@PostMapping("/statistics/company")
	@ApiOperation(value = "企业完成投资情况")
	public R<ChartsVO> statisticsCompany(@RequestBody BaseInvestmentExecutionNewDTO baseInvestmentExecutionDTO) {
		String filingUnitId = baseInvestmentExecutionDTO.getFilingUnitId();
		if (StringUtil.isBlank(filingUnitId)){
			return new R<>(CustomCode.builder().message("单位为空").code(1999).success(false).build());
		}
		R<ChartsVO> result = new R<>(CommonCode.SUCCESS);
		result.setPageData(baseInvestmentExecutionService.statisticsCompany(baseInvestmentExecutionDTO));
		return result;
	}

	/**
	 * 各类重点项目投资计划完成情况
	 * @param baseInvestmentExecutionDTO
	 * @return
	 */
	@PostMapping("/statistics/projectNature")
	@ApiOperation(value = "各类重点项目投资计划完成情况")
	public R<ChartsVO> statisticsProjectNature(@RequestBody BaseInvestmentExecutionNewDTO baseInvestmentExecutionDTO) {
		R<ChartsVO> result = new R<>(CommonCode.SUCCESS);
		result.setPageData(baseInvestmentExecutionService.statisticsProjectNature(baseInvestmentExecutionDTO));
		return result;
	}

//	/**TODO DEL
//	 * 重大项目投资进度 柱状图
//	 * @param baseInvestmentExecutionDTO
//	 * @return
//	 */
//	@PostMapping("/statistics/mainProject")
//	@ApiOperation(value = "重大项目投资进度 柱状图")
//	public R<ChartsVO> statisticsMainProject(@RequestBody BaseInvestmentExecutionNewDTO baseInvestmentExecutionDTO) {
//		R<ChartsVO> result = new R<>(CommonCode.SUCCESS);
//		result.setPageData(baseInvestmentExecutionService.statisticsMainProject(baseInvestmentExecutionDTO));
//		return result;
//	}

	@PostMapping("/statistics/project/company")
	@ApiOperation(value = "项目执行情况按股权和固定资产分类", notes = "传入fillingUnitIds、fillingMonth")
	public R<EffectiveInvestmentVO> statisticsProjectCompany(@RequestBody BaseInvestmentExecutionNewDTO baseInvestmentExecutionDTO){
		return R.data(baseInvestmentExecutionService.statisticsProjectByCompany(baseInvestmentExecutionDTO));
	}

	@PostMapping("/statistics/project/projectNature")
	@ApiOperation(value = "项目执行情况按项目类别分类", notes = "传入fillingUnitIds、fillingMonth")
	public R<List<ExecutionProjectSituationVO>> statisticsProjectProjectNature(@RequestBody BaseInvestmentExecutionNewDTO baseInvestmentExecutionDTO){
		return R.data(baseInvestmentExecutionService.statisticsProjectByProjectNature(baseInvestmentExecutionDTO));
	}

	/**
	 * 生成excel文件
	 * @param
	 * @return
	 */
	@GetMapping("/exportImportFile")
	@ApiOperation(value = "生成excel文件")
	public ObjResult export(@RequestParam(value = "fillYear",required = false) String fillYear){
		PageData pd = new PageData();
		if(StringUtils.isBlank(fillYear)) {
			return new ObjResult("年度不能为空");
		}
		pd.put("key", baseInvestmentExecutionService.export(fillYear));
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		objResult.setPageData(pd);
		return objResult;
	}

	/**
	 * 下载excel文件 并删除
	 *
	 * @param key
	 * @param response
	 */
	@GetMapping("/downloadNew/{key}")
//    @PassToken
	public void downloadNew(@PathVariable String key, HttpServletResponse response) {
		baseInvestmentExecutionService.download(key, response);
	}
}
